<?php
/**
 * Created by PhpStorm.
 * User: jungshen
 * Date: 2018/8/15
 * Time: 17:06
 */

namespace app\swoole\controller;

use think\swoole\Server;
use Db;
class ChatServer extends Server
{
    protected $host = '0.0.0.0';
    protected $port = 9502;
    protected $serverType = 'socket';
    /**
     * Socket的类型
     * @var int
     */
    protected $sockType = SWOOLE_SOCK_TCP|SWOOLE_SSL ;
    protected $option = [
        'worker_num'=> 4,
        'daemonize'	=> true,
        'backlog'	=> 128,
        'ssl_cert_file' => './data/ssl/fullchain.pem',
        'ssl_key_file' =>  './data/ssl/privkey.pem'
    ];

    public function onStart($server){
        echo "service start ... ";
    }
    public function onWorkerStart($server, $worker_id){
        $redis=new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('xoadmin');
        $redis->select(2);
        $server->redis = $redis;
    }
    public function onOpen($server,$req){
        echo "connection open: {$req->fd}\n";
        $token=$req->server['query_string'];
        $info=$this->get_login_info($token,'id,nickname,headimg');
        /*$redis=new \Redis();
        $redis->connect('127.0.0.1', 6379);*/
        //关系绑定
        $server->redis->set('fd_'.$info['id'],$req->fd);
        $server->redis->set('info_'.$req->fd,json_encode($info));
    }
    public function onMessage($server, $frame)
    {
        if($frame->data){
            echo "received message: {$frame->data}\n";
        }
        /*$redis=new \Redis();
        $redis->connect('127.0.0.1', 6379);*/
        $receive_data=json_decode($frame->data,true);
        //判断是否有接收者
        if(isset($receive_data['to_user_id'])){
            //插入数据库
            $info=json_decode($server->redis->get('info_'.$frame->fd),true);
            $sender_id=$msg_data['sender_id']=$info['id'];
            $msg_data['accepter_id']=$receive_data['to_user_id'];
            $msg_data['content']=$receive_data['msg'];
            $msg_data['create_at']=time();
            $msg_data['read_time']=0;
            $id=Db::name('member_msg')->cache('new_msg_num')->insertGetId($msg_data);
            //封装回复消息
            $data['accepter_id']=$receive_data['to_user_id'];
            $data['content']=$receive_data['msg'];
            $data['sender_id']=$sender_id;
            $data['create_at']=time();
            $data['head_img']=$info['headimg'];
            $data['msg_type']='text';
            $data['nickname']=$info['nickname'];
            $data['read_time']=0;
            $data['id']=$id;
            $list[]=$data;
            //给自己广播
            $server->push($frame->fd, json_encode($list));
            //判断接收者是否在线
            $to_user_fd=$server->redis->get('fd_'.$receive_data['to_user_id']);
            if($server->exist($to_user_fd)){
                //给接收者广播
                $server->push($to_user_fd, json_encode($list));
            }
        }
    }

    public function onClose($server, $fd){
        echo "connection close: {$fd}\n";
        //取消关系绑定
        /*$redis=new \Redis();
        $redis->connect('127.0.0.1', 6379);*/
        $info=json_decode($server->redis->get('info_'.$fd),true);
        $server->redis->del('fd_'.$info['id']);
        $server->redis->del('info_'.$fd);
    }

    public function onShutdown($server){
        //kill -15 PID 才会触发
        echo "Shutdown。。。\n";
        $redis=new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('xoadmin');
        $redis->select(2);
        //取消所有关系绑定
        foreach($server->connections as $fd)
        {
            $info=json_decode($redis->get('info_'.$fd),true);
            $redis->del('fd_'.$info['id']);
            $redis->del('info_'.$fd);
        }
    }
    /**
     * 得到当前登录信息
     * @param $token
     * @param null $filed
     * @return array|bool|mixed|null|PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function  get_login_info($token,$filed=null){
        if(!$token)return false;
        $user_token=Db::name('store_member_token')
            ->where('logintoken',$token)
            ->where('expires_in','>=',time())->find();
        if(!$user_token)return false;
        $db=Db::name('store_member')->where('id',$user_token['mid']);
        if($filed){
            if($filed=='id'){
                return $user_token['mid'];
            }
            $usermember=$db->field($filed)->find();
            if(strstr($filed, ',')){
                return $usermember;
            }else{
                return $usermember[$filed];
            }
        }else{
            $usermember=$db->find();
            return $usermember;
        }
    }
}